import redis,json
from mq.setting import * 


class RedisPriorityQueue(object):

    REDIS_CLIENT = None
    QUEUE_NAME = "priority_queue" 
    

    _instance = None
    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super().__new__(cls)  # python3.x中，super()函数的使用语法格式
        return cls._instance
 
    _is_init = False
    def __init__(self,host,port,db,pwd,queue_name=None):
        if self._is_init is False:
            RedisPriorityQueue.REDIS_CLIENT = redis.Redis(host=host,port=port,db=db,password=pwd)
            if queue_name:
                RedisPriorityQueue.QUEUE_NAME = queue_name
            self._is_init = True

    """
    @data_item:数据项
    @priority:优先级
    将元素转换为(优先级, 元素)的形式，并序列化
    """
    @staticmethod
    def put( metadata, priority):
        if type(metadata) is dict:
            metadata = json.dumps(metadata)
        data_node = {metadata:priority}
        RedisPriorityQueue.REDIS_CLIENT.zadd(RedisPriorityQueue.QUEUE_NAME, data_node)

    """
    弹出指定范围元素，并反序列化
    start:起始索引
    end:终止索引
    _2_dict:是否需要转字典类型
    """
    @staticmethod
    def pick(start,end,_2_dict=True):
        data_list = []
        for task, score in RedisPriorityQueue.REDIS_CLIENT.zrevrange(RedisPriorityQueue.QUEUE_NAME, start, end, withscores=True):  
            if _2_dict:
                task = json.loads(task)
            data_list.append(
                (task,score)
            )
        return data_list
    
    @staticmethod
    def pick_high_one(_2_dict=True):
        if RedisPriorityQueue.length() == 0:
            return "No Data"
        
        for task,score in RedisPriorityQueue.REDIS_CLIENT.zrevrange(RedisPriorityQueue.QUEUE_NAME,0,0,withscores=True):
            if _2_dict:
                task = json.loads(task)
            return (task,score)


    """
    删除数据
    """
    @staticmethod
    def remove(metadata):
        if type(metadata) is dict:
            metadata = json.dumps(metadata)
        RedisPriorityQueue.REDIS_CLIENT.zrem(RedisPriorityQueue.QUEUE_NAME, metadata)

    """
    获取数据长度
    """
    @staticmethod
    def length():
        return RedisPriorityQueue.REDIS_CLIENT.zcard(RedisPriorityQueue.QUEUE_NAME) 

 

queue = RedisPriorityQueue(REDIS_HOST,REDIS_PORT,REDIS_DB,REDIS_PWD)
 